/*******************************************************************************
* This file provides the API for the SPI module.
*
* Author: Kong Wai Weng
* Email:  waiweng83@gmail.com
*******************************************************************************/



#include "hal_spi.h"



/*******************************************************************************
* PRIVATE FUNCTION PROTOTYPES                                                  *
*******************************************************************************/

static unsigned int prv_uiTransferSpi1(unsigned int uiData);



/*******************************************************************************
* PUBLIC FUNCTION: vInitSpi1
*
* PARAMETERS:
* ~ void
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Initialize the SPI 1 module.
*
*******************************************************************************/
void vInitSpi1(void)
{
	// Disbale SPI module if enabled previously.
	CloseSPI1();
	
	// Configure interrupt.
	ConfigIntSPI1(	SPI_INT_DIS &		// SPI interrupt disabled.
					SPI_INT_PRI_0 );	// Interrupt priority 0.
	
	// Open the SPI.
	OpenSPI1(	ENABLE_SCK_PIN &			// Internal SPI clock is enabled.
				ENABLE_SDO_PIN &			// SDO pin is enabled and controlled by the module.
				SPI_MODE16_OFF &			// Communication is byte-wide (8 bits).
				SPI_SMP_OFF &				// Input data sampled at middle of data output time.
				SPI_CKE_ON &				// Serial output data changes on transition from active clock state to Idle clock state.
				SLAVE_ENABLE_OFF &			// SS pin is not used by the module. Pin controlled by port function.
				CLK_POL_ACTIVE_HIGH &		// Idle state for clock is a low level. Active state is a high level.
				MASTER_ENABLE_ON &			// Master mode.
				SEC_PRESCAL_1_1 &			// Secondary prescale 1:1 (Frequency = 10MHz).
				PRI_PRESCAL_4_1,			// Primary prescale 4:1 (Frequency = 10MHz).
				
				FRAME_ENABLE_OFF &			// Framed SPIx support disabled.
				FRAME_SYNC_OUTPUT &			// Frame sync pulse output (master).
				FRAME_POL_ACTIVE_LOW &		// Frame sync pulse is active-low.
				FRAME_SYNC_EDGE_PRECEDE,	// Frame sync pulse precedes first bit clock.
				
				SPI_ENABLE &				// Enables module and configures SCK, SDO, SDI and SS as serial port pins.
				SPI_IDLE_CON &				// Continue module operation in Idle mode.
				SPI_RX_OVFLOW_CLR	);		// Clear Receive Overflow Flag bit.
	
	// Read the SPI to clear the buffer.
	ReadSPI1();
}	



/*******************************************************************************
* PUBLIC FUNCTION: vWriteSpi1
*
* PARAMETERS:
* ~ uiData - Data to send.
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Send data via SPI 1.
*
*******************************************************************************/
void vWriteSpi1(unsigned int uiData)
{
	prv_uiTransferSpi1(uiData);
}



/*******************************************************************************
* PUBLIC FUNCTION: uiReadSpi1
*
* PARAMETERS:
* ~ void
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Send data via SPI 1.
*
*******************************************************************************/
unsigned int uiReadSpi1(void)
{
	return prv_uiTransferSpi1(0xff);
}	



/*******************************************************************************
* PRIVATE FUNCTION: prv_uiTransferSpi1
*
* PARAMETERS:
* ~ uiData	- Data to send.
*
* RETURN:
* ~ Data received.
*
* DESCRIPTIONS:
* Transfer data via SPI 1.
*
*******************************************************************************/
static unsigned int prv_uiTransferSpi1(unsigned int uiData)
{
	// Transmit the data.
	WriteSPI1(uiData);
	
	// Wait for the new data in receive buffer.
	while (DataRdySPI1() == 0);
	
	// Read and return the received data.
	return ReadSPI1();
}
